﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using AFI.Speargun.Web.Models;
using System.Web.Security;
using AFI.Speargun.Web.Services.Models;
using AFI.Speargun.Web.Core;

namespace AFI.Speargun.Web.Services
{
    public class Service : IService
    {
        private ISpeargunRepository _repository;

        public Service()
            : this(new EntitySpeargunRepository())
        {

        }

        public Service(ISpeargunRepository repository)
        {
            _repository = repository;
        }

        public IEnumerable<SInventoryChecking> ListInventoryCheckings()
        {
            var q = _repository.ListInventoryCheckings();

            foreach (var i in q)
            {
                i.DepartmentReference.Load();
            }

            return from p in q
                   select new SInventoryChecking
                   {
                       InventoryCheckingId = p.InventoryCheckingId,
                       CreateBy = Membership.GetUser(p.CreateBy, false).ToString(),
                       CreateDate = p.CreateDate,
                       Department = p.Department.Appellation,
                       Status = (InventoryCheckingStatus)p.Status
                   };
        }

        public IEnumerable<SAssetInventory> ListInventoryChecking(Guid inventoryCheckingId)
        {
            List<SAssetInventory> q = new List<SAssetInventory>();

            InventoryChecking inventoryChecking = _repository.GetInventoryChecking(inventoryCheckingId);

            if (!inventoryChecking.DepartmentReference.IsLoaded)
                inventoryChecking.DepartmentReference.Load();

            if (!inventoryChecking.Department.AssetEntry.IsLoaded)
                inventoryChecking.Department.AssetEntry.Load();

            var ae = inventoryChecking.Department.AssetEntry;

            foreach (var i in ae)
            {
                i.AssetInventory.Load();

                if (!i.AssetInventory.IsLoaded)
                    i.AssetInventory.Load();

                if (!i.DepartmentReference.IsLoaded)
                    i.DepartmentReference.Load();

                // current
                AssetInventory ai;
                try
                {
                    ai = (from p in i.AssetInventory
                          where p.InventoryChecking == inventoryChecking
                          select p).First();
                }
                catch
                {
                    ai = null;
                }

                // last
                AssetInventory lastAi;
                try
                {
                    lastAi = (from p in i.AssetInventory
                              where p.InventoryChecking != inventoryChecking
                              orderby p.CheckingDate descending
                              select p).First();
                }
                catch
                {
                    lastAi = null;
                }

                decimal lastQuantity = 0;
                if (lastAi != null)
                    lastQuantity = lastAi.Quantity;


                // add to List
                SAssetInventory item = new SAssetInventory()
                {
                    AssetEntryId = i.AssetEntryId,
                    Appellation = i.Appellation,
                    Department = i.Department.Appellation,
                    LastQuantity = lastQuantity
                };

                if (ai != null)
                {
                    item.CheckingUser = Membership.GetUser(ai.CheckingUser, false).ToString();
                    item.CheckingDate = ai.CheckingDate;
                    item.AssetStatus = (AssetStatus)ai.AssetStatus;
                    item.CheckingResult = (CheckingResult)ai.Result;
                }

                q.Add(item);
            }

            return q;
        }

        public AssetEntry GetAssetEntry(Guid assetEntryId)
        {
            return _repository.GetAssetEntry(assetEntryId);
        }

        public AssetInventory GetAssetInventory(Guid inventoryCheckingId, Guid assetEntryId)
        {
            var q = _repository.ListAssetInventories(assetEntryId);
            var inventoryChecking = _repository.GetInventoryChecking(inventoryCheckingId);

            AssetInventory ai;
            try
            {
                ai = (from p in q
                      where p.InventoryChecking == inventoryChecking
                      select p).First();
            }
            catch
            {
                ai = null;
            }

            return ai;
        }

        public void CreateAssetInventory(Guid inventoryCheckingId, Guid assetEntryId, AssetInventory assetInventory)
        {
            assetInventory.AssetInventoryId = Guid.NewGuid();
            assetInventory.CheckingDate = DateTime.Now;
            assetInventory.CheckingUser = (Guid)Membership.GetUser(OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name, false).ProviderUserKey;

            assetInventory.AssetEntry = _repository.GetAssetEntry(assetEntryId);
            assetInventory.InventoryChecking = _repository.GetInventoryChecking(inventoryCheckingId);

            _repository.CreateAssetInventory(assetInventory);
        }

        public void EditAssetInventory(AssetInventory assetInventory)
        {
            _repository.EditAssetInventory(assetInventory);
        }
    }
}
